TCP/IP网络编程 —— 套接字类型与协议设置

前言

上一篇博文讲解了Linux下的套接字的实现过程,其中涉及到了一些函数,我们只是直接调用了它们,并没有过多的解释,那么函数的具体用法在这篇博客以及接下来的几篇中将会进行详细的介绍,本篇介绍的是创建套接字的函数socket()。

socket()

#include <sys/socket.h>
int socket(int domain, int type, int protocol);
    -> 成功时返回文件描述符,失败时返回-1。
    * domain      套接字中使用的协议族(Protocol Family)信息。
    * type        套接字数据传输类型信息。
    * protocol    计算机间通信中使用的协议信息。

相信看过前一篇的对这个函数并不陌生,但是对函数中的这几个参数可能就不是很明白了,没有关系,我们慢慢道来。

协议族(Protocol Famliy)

奶油意大利面和番茄意大利面都属于意大利面的一种,相似的,套接字通信中的协议也是有分类的。socket函数的第一个参数就是传递套接字中使用的协议分类信息。此协议分类信息我们便称之为协议族,可分成如下几类:

-------------------------------------------------
名 称                        协 议 族
-------------------------------------------------
PF_INET                     IPv4互联网协议族
PF_INET6                    IPv6互联网协议族
PF_LOCAL                    本地通信的UNIX协议族
PF_PACKET                   底层套接字的协议族
PF_IPX                      IPX Novell协议族

以上的协议族在头文件sys/socket.h中声明;另外我们将重点放在PF_INET对应的IPv4互联网协议族上,因为其他协议族并不常用或尚未普及。

套接字类型(Type)

套接字类型指的是套接字的数据传输方式,由socket函数的第二个参数传递;下面介绍2种具有代表性的数据传输方式:

套接字类型1:面向连接的套接字(SOCK_STREAM)

如果向socket函数的第二个参数传递SOCK_STREAM,将创建面向连接的套接字,此传输方式的特征如下:

  • 传输过程中数据不会消失
  • 按序传输数据
  • 传输的数据不存在数据边界

套接字类型2:面向消息的套接字(SOCK_DGRAM)

如果向socket函数的第二个参数传递SOCK_DGRAM,将创建面向消息的套接字,此传输方式的特征如下:

  • 强调快速传输而非传输顺序
  • 传输的数据可能丢失也可能损毁
  • 传输的数据有数据边界
  • 限制每次传输的数据大小

注:面向连接的套接字需要有相同类型的另一套接字与之连接,而面向消息的套接字不存在连接的概念。

协议的最终选择

下面讲解socket函数的第三个参数,该参数决定最终采用的协议;在大部分情况下,传递前两个参数即可创建所需的套接字,所以可以向第三个参数传递0;如果数据传输方式相同,但协议不同,则此时需要通过第三个参数指定具体的协议信息。下面用两个例子来理解第三个参数。
创建满足如下要求的套接字:

1.“IPv4协议族中面向连接的套接字”
很明显,前两个参数就是PF_INET和SOCK_STREAM了,而满足前两个条件的协议就只有IPPROTO_TCP了,因此我们可以向第三个参数传递0或是如下格式:
int tcp_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);  

2."IPv4协议族中面向消息的套接字"
同样的,前两个参数就是PF_INET和SOCK_DGRAM,满足前两个条件的协议只有IPPROTO_UDP,所以该套接字如下:
int udp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

自此,整个socket函数就算是讲解完了,大家可以回过头去看看前一篇博客给出的demo,相信你们对socket函数部分会比之前有更深的理解。
本篇完结,白白。。。